package queue.priorityQueue;

import queue.Queue;

/**
 * @author yyz
 * @create 2024-01-09 17:38
 */
@SuppressWarnings("all")
public class PriorityQueue1<E extends Priority> implements Queue<E> {
    Priority[] array;
    int capacity;
    int size = 0;

    public PriorityQueue1(int capacity) {
        this.capacity = capacity;
        array = new Priority[capacity];
    }

    @Override
    public boolean offer(E value) {
        if (isFull()) {
            return false;
        }
        array[size++] = value;
        return true;
    }


    @Override
    public E poll() {
        if (isEmpty()) {
            return null;
        }
        int max = selectMax();
        Priority val = array[max];
        remove(max);
        return (E) val;
    }

    private void remove(int max) {
        if (array.length - 1 > max) {
            System.arraycopy(array, max + 1, array, max, size - 1 - max);
        }
        array[--size] = null;// help GC
    }

    private int selectMax() {
        int max = 0;
        for (int i = 1; i < size; i++) {
            if (array[max].priority() < array[i].priority()) {
                max = i;
            }
        }
        return max;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        int max = selectMax();
        return (E) array[max];
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == capacity;
    }
}
